home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 036a / os2info.zip / DOS-SYS.OS2 < prev    next >
Text File  |  1991-05-20  |  12KB  |  379 lines

  1. Wed Sep 12 09:55:43 1990
  2. --------------------------
  3. TITLE: OS/2 1.2 DOS.SYS interface
  4.  
  5. Yet another of OS/2's mysteries has been unraveled.  OS/2 1.2 allows the
  6. Task Manager to initiate programs in the DOS box, but does not document
  7. the mechanism that is used, so it has not been possible to do the same
  8. thing from other applications.  Here is set of messages from the FidoNet
  9. OS/2 echo that documents the DOS.SYS driver interface that performs this
  10. magic, and sample code to show its use.  You'll also find a paragraph
  11. from Peter Fitzsimmons describing how he figured this all out.
  12.  
  13. Credit goes to Peter Fitzsimmons for doing the original research, and to
  14. Bill Andrus for tying together the loose ends and creating a usable
  15. program out of it.
  16.  
  17.  
  18. 309/366 09 Sep 90 08:12:06
  19. From:   Peter Fitzsimmons
  20. To:     All
  21. Subj:   new trick
  22. Attr:
  23. ------------------------------------------------
  24.  
  25. I've figured out a little bit about DOS.SYS....
  26.  
  27. This little sample program uses DOS.SYS to change to C:,  change to \OS2, and
  28. run "edlin \config.sys".
  29.  
  30. When you Q)uit edlin, the session that was in the foreground prior to flipping
  31. to the dos box (not nec the session that 2dos.exe was running in) is restored
  32. to the foreground.
  33.  
  34. I have not yet figured out how to reboot through DOS.SYS -- but this is an easy
  35. thing to code yourself (such a program is included with Maximus).
  36.  
  37. -[2dos.c beings]----------------------------------
  38.  
  39.  #include <stdio.h>
  40.  #include <string.h>
  41.  #include <stdlib.h>
  42.  #define INCL_DOS
  43.  #define INCL_DOSERRORS
  44.  #define INCL_WINSWITCHLIST
  45.  #include <os2.h>
  46.  
  47.  void jump2dos(void);
  48.  
  49.  static char *cmd = "\x80 C:\r"
  50.                     "\x80 CD\\OS2\r"
  51.                     "\x80 edlin \\config.sys\r";
  52.  
  53.  void cdecl main(void)
  54.  {
  55.      HFILE hf;
  56.      USHORT rc, dummy;
  57.  
  58.      rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  59.          OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  60.          OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  61.      if(!rc){
  62.          rc = DosWrite(hf, cmd, strlen(cmd)+1, &dummy);
  63.          DosClose(hf);
  64.          if(!rc)
  65.              jump2dos();
  66.          else if(rc == ERROR_NOT_READY)
  67.              printf("A program is already running in the DOS box\n");
  68.          else
  69.              printf("Unexpected OS/2 error SYS%04u\n", rc);
  70.      }
  71.      else
  72.          printf("DOS.SYS not installed (sys%04u)\n", rc);
  73.      DosBeep(1000, 100);
  74.  }
  75.  
  76.  void jump2dos(void)
  77.  {
  78.      USHORT num, i;
  79.      void *buf = malloc(32000);
  80.      SWENTRY *swe;
  81.      HSWITCH fgHandle;
  82.      SEL selGlobalSeg, selLocalSeg;
  83.      GINFOSEG FAR * volatile pgis;
  84.      UCHAR sgDos;
  85.  
  86.      /* find out who is in the foregound,  so we know who to switch
  87.       * back to after the dos box is done.  This method only works
  88.       * if the foreground session is NOT a pm program.  If it is a
  89.       * pm program,  the "Task List" will be the active app after
  90.       * the task switch
  91.       */
  92.      DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  93.      pgis = MAKEPGINFOSEG(selGlobalSeg);
  94.      fgHandle = WinQuerySwitchHandle(0L, pgis->pidForeground);
  95.  
  96.      /* Find the switch list handle of the DOS box: */
  97.      num = WinQuerySwitchList(0L, buf, 32000);
  98.      swe = (SWENTRY *)((USHORT *)buf + 1);
  99.      for(i=0; i<num; i++){
  100.          if(!strcmp("DOS", swe[i].swctl.szSwtitle)){
  101.              WinSwitchToProgram(swe[i].hswitch);
  102.              break;
  103.          }
  104.      }
  105.      free(buf);
  106.      if(i==num){
  107.          printf("This system is configured without a dos box!\n");
  108.          return;
  109.      }
  110.      if(fgHandle){
  111.          DosSleep(100L);     /* give a moment for the task switch */
  112.          sgDos = pgis->sgCurrent;
  113.  
  114.          /*
  115.           * Wait (poll) current screen group -- waiting for the DOS
  116.           * program to end.  I don't like polling,  but this is the only
  117.           * solution I can come up with.  If you don't mind the "Task
  118.           * List" always being brought the the fore after the dos progam
  119.           * ends,  you can forget about all of this and exit() after the
  120.           * WinSwitchToProgram(), above.
  121.           */
  122.  
  123.          while( sgDos == pgis->sgCurrent )
  124.              DosSleep(500L);
  125.  
  126.          WinSwitchToProgram(fgHandle);   /* back to where we started */
  127.      }
  128.  }
  129.  
  130.  #if 0
  131.  
  132.  Comments
  133.  --------
  134.  
  135.  The only reason this program works is becuase WinSwitchToProgram()
  136.  allows you to:
  137.  
  138.      1) Switch a session to the foreground which is not one of your own
  139.         child sessions.
  140.  
  141.      2) Switch a session to the foreground when you are not running
  142.         in the foreground yourself.
  143.  
  144.  Acording to the documentation (IBM, v1.20),  you are not supposed to
  145.  be able to do either of these things.  However,  the "File Manager",
  146.  from what I can figure out,  uses this method to switch to the DOS
  147.  box too,  so I am confident that this program will continue to work
  148.  under OS/2 1.2x.
  149.  
  150.  Peter Fitzsimmons, A:WARE Inc. Thu  09-06-1990  22:15:11
  151.  #endif
  152.  
  153. -[2dos.c ends]----------------------------------
  154.  
  155. --- Maximus-CBCS v1.02-OS/2-r2
  156.  * Origin: Pete's Point (1:250/628.1)
  157.  
  158.  
  159. 311/366 09 Sep 90 08:12:29
  160. From:   Peter Fitzsimmons
  161. To:     All
  162. Subj:   new trick part 2
  163. Attr:
  164. ------------------------------------------------
  165.  
  166. And here is how to reboot via dos.sys:
  167.  
  168. ----[reboot.c begins]----
  169.  
  170.  #include <stdio.h>
  171.  #define INCL_DOS
  172.  #include <os2.h>
  173.  
  174.  void cdecl main(void)
  175.  {
  176.      HFILE hf;
  177.      USHORT rc, dummy;
  178.  
  179.      rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  180.          OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  181.          OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  182.      if(!rc){
  183.          DosShutdown(0L);
  184.          DosDevIOCtl(NULL, NULL, 0xab, 0xd5, hf);        /* reboot */
  185.          DosClose(hf);
  186.      }
  187.      else
  188.          printf("DOS.SYS not installed (sys%04u)\n", rc);
  189.  }
  190. ----[reboot.c ends]------
  191.  
  192. How did I figure all of this DOS.SYS stuff out, you ask?  I wrote my own DOS$
  193. device driver,  and simply had it report what the programs that use the real
  194. DOS$ (boot.com, pmfile.exe) were trying to do with it.  (I was bored one day at
  195. work).
  196.  
  197. Pete.
  198.  
  199. --- Maximus-CBCS v1.02-OS/2-r2
  200.  * Origin: Pete's Point (1:250/628.1)
  201.  
  202.  
  203. 361/366 10 Sep 90 23:14:13
  204. From:   Bill Andrus
  205. To:     Peter Fitzsimmons
  206. Subj:   new trick part 3
  207. Attr:
  208. ------------------------------------------------
  209. Okay, here's the complete program that everyone says can't be done with the
  210. current documentation:
  211.  
  212. === CALLDOS.C ========================================================
  213.  
  214. /* Compiles with IBM C/2 1.1 and its MAKE/2 2.0 using:
  215.  
  216. ###############################################################
  217. #  Make file for CALLDOS.C                                    #
  218. #                                                             #
  219. #  use MAKE CALLDOS.C                                         #
  220. #                                                             #
  221. ###############################################################
  222. model=S            # use large model when debugging -- bugs JUMP out at you
  223. mode=p
  224. linklibs=$(model)libce$(mode).lib os2.lib
  225. CFLAGS=-A$(model) -Lp -Oxrn -Zpel -W3 -G2 -Gw -J -nologo
  226. LINK=D:\C\Bin\Link
  227.  
  228. calldos.exe : calldos.obj
  229.  $(LINK)
  230. calldos.obj,calldos.exe/A:16/FAR/NOD/PACKD/ST:3000,NUL.MAP,$(linklibs);
  231.  
  232. calldos.obj : calldos.c
  233.  !CL $(CFLAGS) -c $?
  234.  
  235. */
  236.  
  237. /* Merge of Peter Fitzsimmons' CALLBOX.C and 2DOS.C programs */
  238.  
  239. #include <stdio.h>
  240. #include <string.h>
  241. #include <stdlib.h>
  242. #define INCL_DOS
  243. #define INCL_DOSERRORS
  244. #define INCL_WINSWITCHLIST
  245. #include <os2.h>
  246.  
  247. void jump2dos(void)
  248. {
  249.     USHORT num, i;
  250.     void *buf = malloc(32000);
  251.     SWENTRY *swe;
  252.     HSWITCH fgHandle;
  253.     SEL selGlobalSeg, selLocalSeg;
  254.     GINFOSEG FAR * volatile pgis;
  255.     UCHAR sgDos;
  256.  
  257.     /* find out who is in the foregound,  so we know who to switch
  258.      * back to after the dos box is done.  This method only works
  259.      * if the foreground session is NOT a pm program.  If it is a
  260.      * pm program,  the "Task List" will be the active app after
  261.      * the task switch
  262.      */
  263.     DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  264.     pgis = MAKEPGINFOSEG(selGlobalSeg);
  265.     fgHandle = WinQuerySwitchHandle(0L, pgis->pidForeground);
  266.  
  267.     /* Find the switch list handle of the DOS box: */
  268.     num = WinQuerySwitchList(0L, buf, 32000);
  269.     swe = (SWENTRY *)((USHORT *)buf + 1);
  270.     for(i=0; i<num; i++){
  271.         if(!strcmp("DOS", swe[i].swctl.szSwtitle)){
  272.             WinSwitchToProgram(swe[i].hswitch);
  273.             break;
  274.         }
  275.     }
  276.     free(buf);
  277.     if(i==num){
  278.         printf("This system is configured without a dos box!\n");
  279.         return;
  280.     }
  281.     if(fgHandle){
  282.         DosSleep(500L);     /* give a moment for the task switch */
  283.         sgDos = pgis->sgCurrent;
  284.  
  285.         /*
  286.          * Wait (poll) current screen group -- waiting for the DOS
  287.          * program to end.  I don't like polling,  but this is the only
  288.          * solution I can come up with.  If you don't mind the "Task
  289.          * List" always being brought the the fore after the dos progam
  290.          * ends,  you can forget about all of this and exit() after the
  291.          * WinSwitchToProgram(), above.
  292.          */
  293.  
  294.         while( sgDos == pgis->sgCurrent )
  295.             DosSleep(500L);
  296.  
  297.         WinSwitchToProgram(fgHandle);   /* back to where we started */
  298.     }
  299. }
  300.  
  301. #if 0
  302.  
  303. Comments
  304. --------
  305.  
  306. The only reason this program works is becuase WinSwitchToProgram()
  307. allows you to:
  308.  
  309.     1) Switch a session to the foreground which is not one of your own
  310.        child sessions.
  311.  
  312.     2) Switch a session to the foreground when you are not running
  313.        in the foreground yourself.
  314.  
  315. Acording to the documentation (IBM, v1.20),  you are not supposed to
  316. be able to do either of these things.  However,  the "File Manager",
  317. from what I can figure out,  uses this method to switch to the DOS
  318. box too,  so I am confident that this program will continue to work
  319. under OS/2 1.2x.
  320.  
  321. Peter Fitzsimmons, A:WARE Inc. Thu  09-06-1990  22:15:11
  322. #endif
  323.  
  324. void main(int argc, char **argv)
  325. {
  326.     HFILE hf;
  327.     USHORT rc, dummy;
  328.     static char cmd[256];
  329.     int i;
  330.  
  331.     if( argc < 2 ){
  332.  
  333.  printf("\nUsage CALLDOS  <command>\n\n");
  334.  printf("   Each <command> with blanks should be enclosed by quotes\n\n");
  335.  printf("For example:\n");
  336.  printf("CALLDOS C: \"CD \\OS2\" \"DIR > \\DIR.LST\" \"CD \\\"\n\n");
  337.  printf("Will make C:\\OS2 current, list the files to C:\\DIR.LST,\n");
  338.  printf("and switch back to C:\\.\n\n");
  339.  printf("If invoked while a PM session is current, the focus returns,\n");
  340.  printf("to the Task List, else returns to the current session.\n\n");
  341.         exit (255);
  342.     }
  343.     cmd[0] = '\0';
  344.     for(i=1; i<argc; i++){
  345.         strcat(cmd, "\x80 ");
  346.         strcat(cmd, argv[i]);
  347.         strcat(cmd, "\r");
  348.         if( i != (argc-1) )
  349.             strcat(cmd, " ");
  350.     }
  351.     rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  352.         OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  353.         OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  354.     if(!rc){
  355.         rc = DosWrite(hf, cmd, strlen(cmd)+1, &dummy);
  356.         DosClose(hf);
  357.         if(!rc)
  358.             jump2dos();
  359.         else if(rc == ERROR_NOT_READY) {
  360.             printf("A program is already running in the DOS box\n");
  361.             exit (1);
  362.         }
  363.         else {
  364.             printf("Unexpected OS/2 error SYS%04u\n", rc);
  365.             exit (2);
  366.         }
  367.     }
  368.     else {
  369.         printf("DOS.SYS not installed (sys%04u)\n", rc);
  370.         exit (3);
  371.     }
  372.     DosBeep(1000, 100);
  373. }
  374.  
  375. === End of CALLDOS.C ===============================================
  376.  
  377. --- msged 2.00 OS/2
  378.  * Origin: RC13's OS/2 Point in the Pit (1:109/301.10@fidonet)
  379.